package com.yanqu.road.server.gameplayer.module.activity.ruishou;

import com.alibaba.fastjson.JSON;
import com.yanqu.road.entity.activity.ruishou.*;
import com.yanqu.road.entity.activity.ruishou.config.RuiShouActionConfig;
import com.yanqu.road.entity.activity.ruishou.config.RuiShouActionTenConfig;
import com.yanqu.road.entity.activity.ruishou.config.RuiShouAreaConfig;
import com.yanqu.road.entity.activity.ruishou.config.RuiShouMonsterConfig;
import com.yanqu.road.entity.config.system.NormalWeightItem;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.ruishou.LogRuiShouChooseReward;
import com.yanqu.road.entity.log.ruishou.LogRuiShouShoot;
import com.yanqu.road.logic.bussiness.activity.RuiShouBussiness;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.RuiShouProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.ruishou.RuiShouMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.pb.RuiShouPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.*;

public class RuiShouModule extends GeneralModule {

    private RuiShouUserData userData;

    /**
     * 区域数据
     */
    private Map<Integer, RuiShouAreaData> areaDataMap = new HashMap<>();

    public RuiShouModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config != null && ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            userData = RuiShouBussiness.getRuiShouUserData(config.getActivityId(), player.getUserId());
            // 加载区域数据
            areaDataMap = RuiShouBussiness.getRuiShouAreaDataMap(config.getActivityId(), player.getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                RuiShouBussiness.addRuiShouUserData(userData);
            } else if (userData.isUpdateOption()) {
                RuiShouBussiness.updateRuiShouUserData(userData);
            }
        }
        for (RuiShouAreaData areaData : areaDataMap.values()) {
            if (areaData.isInsertOption()) {
                RuiShouBussiness.addRuiShouAreaData(areaData);
            } else if (areaData.isUpdateOption()) {
                RuiShouBussiness.updateRuiShouAreaData(areaData);
            }
        }
        return true;
    }


    @Override
    public void afterLogin() {
        initSystem();
    }

    /**
     * 系统初始化
     */
    public void initSystem() {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.RuiShou.getValue())) {
            return;
        }
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        syncConfig();
        initUserData();
        checkAreaDataLock();
        syncUserData();
    }

    /**
     * 检测区域数据是否解锁
     */
    private void checkAreaDataLock() {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        if (userData == null) {
            return;
        }
        boolean needSync = false;
        for (RuiShouAreaConfig areaConfig : config.getAreaConfigMap().values()) {
            if ("0".equals(areaConfig.getUnlock())) {
                // 默认解锁
                initAreaData(areaConfig.getArea());
                needSync = true;
            } else {
                // 判断下有没有解锁
                String[] split = areaConfig.getUnlock().split("=");
                int monsterId = Integer.parseInt(split[0]);
                int num = Integer.parseInt(split[1]);
                if (userData.getKillMonsterCntMap().getOrDefault(monsterId, 0) >= num) {
                    // 可解锁
                    initAreaData(areaConfig.getArea());
                    needSync = true;
                }
            }
        }
        if (needSync) {
            syncUserData();
        }
    }

    /**
     * 初始化区域
     *
     * @param area
     */
    private void initAreaData(int area) {
        if (areaDataMap.containsKey(area)) {
            // 已解锁
            return;
        }
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        RuiShouAreaData areaData = new RuiShouAreaData();
        areaData.setActivityId(config.getActivityId());
        areaData.setUserId(player.getUserId());
        areaData.setAreaId(area);
        areaData.setFightMonsterDataMap(new HashMap<>());
        areaData.setMonsterDataMap(new HashMap<>());
        areaData.setReset(false);
        areaData.setLockReward(false);
        areaData.setInsertOption();
        areaDataMap.put(area, areaData);

        // 初始化区域怪物
        initAreaMonster(areaData);
    }

    /**
     * 初始化区域瑞兽
     *
     * @param areaData 区域数据
     */
    private void initAreaMonster(RuiShouAreaData areaData) {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        // 初始化一下怪物区域
        for (int pos = 1; pos <= 3; pos++) {
            RuiShouFightMonsterData fightMonsterData = new RuiShouFightMonsterData();
            fightMonsterData.setId(0);
            fightMonsterData.setPos(pos);
            fightMonsterData.setHp(0);
            areaData.getFightMonsterDataMap().put(pos, fightMonsterData);
        }
    }

    /**
     * 同步配置
     */
    private void syncConfig() {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        RuiShouProto.RuiShouConfigSyncMsg.Builder syncConfigMsg = RuiShouProto.RuiShouConfigSyncMsg.newBuilder();
        for (RuiShouAreaConfig areaConfig : config.getAreaConfigMap().values()) {
            syncConfigMsg.addArea(RuiShouPb.parseRuiShouAreaConfigMsg(areaConfig, player.getLanguage()));
        }
        for (RuiShouMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
            syncConfigMsg.addMonster(RuiShouPb.parseRuiShouMonsterConfigMsg(monsterConfig, player.getLanguage()));
        }
        for (RuiShouActionConfig actionConfig : config.getActionConfigMap().values()) {
            syncConfigMsg.addAction(RuiShouPb.parseRuiShouActionConfigMsg(actionConfig));
        }
        player.sendPacket(ClientProtocol.U_RUI_SHOU_CONFIG_SYNC, syncConfigMsg);
    }

    private synchronized void initUserData() {
        // 没有活动
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }
        // 已经有数据了
        if (userData != null && userData.getActivityId() == config.getActivityInfo().getActivityId()) {
            return;
        }
        // 初始化用户数据
        RuiShouUserData tmpUserData = new RuiShouUserData();
        tmpUserData.setActivityId(config.getActivityInfo().getActivityId());
        tmpUserData.setUserId(player.getUserId());
        tmpUserData.setKillMonsterCntMap(new HashMap<>());
        tmpUserData.setScore(0);
        tmpUserData.setInsertOption();
        userData = tmpUserData;

        // 重置区域数据
        areaDataMap = new HashMap<>();
    }

    /**
     * 同步用户数据
     */
    private void syncUserData() {
        if(userData == null){
            return;
        }
        RuiShouProto.RuiShouUserDataSyncMsg.Builder builder = RuiShouProto.RuiShouUserDataSyncMsg.newBuilder();
        for (RuiShouAreaData areaData : areaDataMap.values()) {
            builder.addAreaData(RuiShouPb.parseRuiShouAreaDataMsg(areaData));
        }
        // 计算下怪物击杀数量
        builder.setKillCnt(userData.getAllKillMonsterCnt());
        builder.setScore(userData.getScore());
        player.sendPacket(ClientProtocol.U_RUI_SHOU_USER_DATA_SYNC, builder);
    }


    /**
     * 区域数据
     */
    public RuiShouAreaData getAreaData(int areaId) {
        return areaDataMap.get(areaId);
    }

    /**
     * 选择奖励
     *
     * @param areaId    地区id
     * @param rewardStr 选择的奖励 怪物id=奖励id#怪物id=奖励id#怪物id=奖励id
     */
    public int chooseReward(int areaId, String rewardStr) {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_RUI_SHOU_CONFIG_NOT_FOUND;
        }
        if (!ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_NOT_OPEN;
        }
        RuiShouAreaConfig areaConfig = config.getRuiShouAreaConfig(areaId);
        if (areaConfig == null) {
            return GameErrorCode.E_RUI_SHOU_AREA_NOT_FOUND;
        }
        if (userData == null) {
            return GameErrorCode.E_RUI_SHOU_USER_NOT_FOUND;
        }
        RuiShouAreaData areaData = getAreaData(areaId);
        if (areaData == null) {
            return GameErrorCode.E_RUI_SHOU_AREA_NOT_FOUND;
        }
        if (areaData.isLockReward()) {
            return GameErrorCode.E_RUI_SHOU_REWARD_IS_LOCK;
        }
        // 算一下有多少个需要自选的
        int needCnt = 0;
        for (RuiShouMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
            if (monsterConfig.getArea() != areaId) {
                continue;
            }
            if (!"0".equals(monsterConfig.getAward())) {
                needCnt++;
            }
        }
        String[] rewardList = rewardStr.split("#");

        if (needCnt != rewardList.length) {
            // 参数不对，选的不对
            return GameErrorCode.E_ERROR_PARAMETER;
        }

        for (String reward : rewardList) {
            String[] split = reward.split("=");
            int monsterId = Integer.parseInt(split[0]);
            int rewardId = Integer.parseInt(split[1]);
            // 判断下奖励存不存在
            if (!config.getAwardRewardMap().containsKey(monsterId) || !config.getAwardRewardMap().get(monsterId).containsKey(rewardId)) {
                return GameErrorCode.E_ERROR_PARAMETER;
            }
            RuiShouMonsterAwardHelper awardHelper = config.getAwardRewardMap().get(monsterId).get(rewardId);
            // 判断当前次数够不够
            if (awardHelper.getLimit() != -1 && areaData.getChooseAwardCnt(monsterId, rewardId) >= awardHelper.getLimit()) {
                return GameErrorCode.E_RUI_SHOU_AWARD_CHOOSE_LIMIT;
            }
        }
        // 记录下已选择的奖励
        areaData.clearChooseRewardId();
        for (String reward : rewardList) {
            String[] split = reward.split("=");
            int monsterId = Integer.parseInt(split[0]);
            int rewardId = Integer.parseInt(split[1]);
            areaData.setChooseRewardId(monsterId, rewardId);
        }
        // 这里只记录选择数据，先不计数，抽奖后锁定计数

        // 检查区域怪物
        checkAreaMonsterData(areaData);

        // 判断下有没有怪物,有怪物的话需要重置奖励
        for (RuiShouFightMonsterData monsterData : areaData.getFightMonsterDataMap().values()) {
            if (monsterData.getId() == 0 || monsterData.getHp() <= 0) {
                continue;
            }
            monsterData.setReward(PropertyHelper.parsePropertyToString(getMonsterReward(areaData.getAreaId(), monsterData.getId())));
        }

        areaData.setUpdateOption();
        userData.setUpdateOption();

        RuiShouProto.RuiShouChooseRewardRespMsg.Builder respMsg = RuiShouProto.RuiShouChooseRewardRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setAreaData(RuiShouPb.parseRuiShouAreaDataMsg(areaData));
        player.sendPacket(ClientProtocol.U_RUI_SHOU_CHOOSE_REWARD, respMsg);
        return 0;
    }

    /**
     * 区域重置
     *
     * @param areaId 地区id
     */
    public int resetArea(int areaId) {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_RUI_SHOU_CONFIG_NOT_FOUND;
        }
        if (!ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_NOT_OPEN;
        }
        RuiShouAreaConfig areaConfig = config.getRuiShouAreaConfig(areaId);
        if (areaConfig == null) {
            return GameErrorCode.E_RUI_SHOU_AREA_NOT_FOUND;
        }
        if (userData == null) {
            return GameErrorCode.E_RUI_SHOU_USER_NOT_FOUND;
        }
        RuiShouAreaData areaData = getAreaData(areaId);
        if (areaData == null) {
            return GameErrorCode.E_RUI_SHOU_AREA_NOT_FOUND;
        }
        // 判断下是否可重置
        if (!areaData.isReset()) {
            return GameErrorCode.E_RUI_SHOU_AREA_DONT_RESET;
        }
        // 改个状态再重置
        areaData.setReset(false);

        // 重置数据
        resetAreaData(areaData);

        areaData.setUpdateOption();
        userData.setUpdateOption();

        RuiShouProto.RuiShouResetRespMsg.Builder respMsg = RuiShouProto.RuiShouResetRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setAreaData(RuiShouPb.parseRuiShouAreaDataMsg(areaData));
        player.sendPacket(ClientProtocol.U_RUI_SHOU_RESET, respMsg);
        return 0;
    }

    /**
     * 重置区域数据
     *
     * @param areaData 区域数据
     */
    public void resetAreaData(RuiShouAreaData areaData) {
        if (areaData == null) {
            return;
        }
        // 重置下怪物数据   重置区域不重置盘面怪物
//        initAreaMonster(areaData);
        // 重置下怪物数据
        for (RuiShouMonsterData monsterData : areaData.getMonsterDataMap().values()) {
            monsterData.setIncrementCnt(0);
            monsterData.setFightCnt(0);
            monsterData.setChooseRewardId(0);
        }
        for (RuiShouFightMonsterData monsterData : areaData.getFightMonsterDataMap().values()) {
            monsterData.setId(0);
            monsterData.setReward("");
            monsterData.setHp(0);
        }
        // 不锁奖励
        areaData.setLockReward(false);
    }

    /**
     * 检测奖励锁定状态，抽奖时检查
     * <p>
     * 进入抽奖时才扣除次数,且锁定奖励状态，不可再选
     *
     * @param areaData 地区数据
     */
    public void checkLockReward(RuiShouAreaData areaData) {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        if (areaData == null) {
            return;
        }
        // 已锁定不处理
        if (areaData.isLockReward()) {
            return;
        }
        // 未锁定，进入锁定状态
        areaData.setLockReward(true);
        // 扣除次数
        for (RuiShouMonsterData monsterData : areaData.getMonsterDataMap().values()) {
            if (monsterData.getChooseRewardId() == 0) {
                continue;
            }
            areaData.addChooseAwardCnt(monsterData.getMonsterId(), monsterData.getChooseRewardId());
        }

        // 记录下日志
        Date logDate = new Date();
        for (RuiShouMonsterData monsterData : areaData.getMonsterDataMap().values()) {
            if (monsterData == null || monsterData.getChooseRewardId() == 0) {
                continue;
            }
            String chooseReward = "";
            if (config.getAwardRewardMap().containsKey(monsterData.getMonsterId()) && config.getAwardRewardMap().get(monsterData.getMonsterId()).containsKey(monsterData.getChooseRewardId())) {
                chooseReward = PropertyHelper.parsePropertyToString(config.getAwardRewardMap().get(monsterData.getMonsterId()).get(monsterData.getChooseRewardId()).getReward());
            }
            AutoLogMgr.add(new LogRuiShouChooseReward(
                    player.getUserId(),
                    config.getActivityId(),
                    areaData.getAreaId(),
                    monsterData.getMonsterId(),
                    monsterData.getChooseRewardId(),
                    chooseReward,
                    logDate
            ));

        }
    }


    /**
     * 模拟测试
     */
    public void mockTest(int userCnt, int areaId) {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        Map<Integer, Integer> cntMap = new HashMap<>();
        int totalTimes = 0;
        for (int userId = 1; userId <= userCnt; userId++) {
            // 初始化一个地区数据
            RuiShouAreaData areaData = new RuiShouAreaData();
            areaData.setActivityId(config.getActivityId());
            areaData.setUserId(userId);
            areaData.setAreaId(areaId);
            areaData.setFightMonsterDataMap(new HashMap<>());
            areaData.setMonsterDataMap(new HashMap<>());
            areaData.setReset(false);
            areaData.setLockReward(false);
            initAreaMonster(areaData);
            // 检查区域怪物
            checkAreaMonsterData(areaData);


            Map<Integer, List<Integer>> monsterCntMap = new HashMap<>();
            Map<Integer, Integer> posCntMap = new HashMap<>();



            int times = 0;
            for (int i = 0; i < 10000; i++) {
                times++;
                if (areaData.getActionIdPool().isEmpty()) {
                    // 抽一个表现池
                    NormalWeightItem randomResult = WeightHelper.getRandomResult(config.getActionTenWeightList());
                    if (randomResult == null) {
                        continue;
                    }
                    // 表现组合id
                    int actionTenId = randomResult.getValue().intValue();
                    RuiShouActionTenConfig actionTenConfig = config.getRuiShouActionTenConfig(actionTenId);
                    if (actionTenConfig != null) {
                        for (Integer actionId : actionTenConfig.getActionIdList()) {
                            areaData.getActionIdPool().addLast(actionId);
                        }
                    }
                }
                // 做个容错,这里还是空，可能就是配置问题了，玩家可能会丢掉一次，记录下日志
                if (areaData.getActionIdPool().isEmpty()) {
                    log.error("【祥瑞赐福】actionIdPool is empty,userId:{}", player.getUserId());
                    continue;
                }
                // 本次表现id
                int actionId = areaData.getActionIdPool().removeFirst();
                // 拿一下表现配置
                RuiShouActionConfig actionConfig = config.getRuiShouActionConfig(actionId);
                if (actionConfig == null) {
                    log.error("【祥瑞赐福】actionId not found ,actionId:{},userId:{}", actionId, player.getUserId());
                    continue;
                }
                // 判断一下怪物撞击
                for (Integer pos : actionConfig.getMovePath()) {
                    if (pos == 0) {
                        // 无撞击
                        continue;
                    }
                    // 计数下
                    posCntMap.put(pos, posCntMap.getOrDefault(pos, 0) + 1);
                    if (!areaData.getFightMonsterDataMap().containsKey(pos)) {
                        continue;
                    }
                    RuiShouFightMonsterData fightMonsterData = areaData.getFightMonsterDataMap().get(pos);
                    if (fightMonsterData.getId() == 0 || fightMonsterData.getHp() <= 0) {
                        // 已死亡或者空的不处理
                        continue;
                    }
                    // 最终血量
                    fightMonsterData.setHp(fightMonsterData.getHp() - 1);
                    if (fightMonsterData.getHp() <= 0) {
                        // 生成新的怪物
                        RuiShouFightMonsterData newFightMonsterData = randomFightMonster(areaData, pos);
                        if (newFightMonsterData != null) {
                            areaData.getFightMonsterDataMap().put(pos, newFightMonsterData);
                        } else {
                            areaData.getFightMonsterDataMap().remove(pos);
                        }

                        // 击杀的是否为祥瑞
                        RuiShouMonsterConfig deadMonsterConfig = config.getRuiShouMonsterConfig(fightMonsterData.getId());

//                        if (deadMonsterConfig.getLevel() > 1) {
//                            List<Integer> list = monsterCntMap.getOrDefault(deadMonsterConfig.getId(), new ArrayList<>());
//                            list.add(times);
//                            monsterCntMap.put(deadMonsterConfig.getId(), list);
//                        }
                        if (deadMonsterConfig.getLevel() == 3) {
                            cntMap.put(times, cntMap.getOrDefault(times, 0) + 1);
                            totalTimes += times;
                        }
                    }
                }
                if (areaData.getFightMonsterDataMap().isEmpty()) {
                    // 结束循环
                    break;
                }

            }

            // 记录一下

        }
        int avg = totalTimes / userCnt;
        for (Map.Entry<Integer, Integer> entry : cntMap.entrySet()) {
            System.out.println(entry.getKey() + "\t" + entry.getValue());
        }
        log.info("sss:{},均值:{}", cntMap, avg);
    }


    /**
     * 发射
     *
     * @param areaId     区域id
     * @param totalTimes 总次数
     */
    public int shoot(int areaId, int totalTimes) {
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_RUI_SHOU_CONFIG_NOT_FOUND;
        }
        if (!ActivityHelper.activityInShowTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_NOT_OPEN;
        }
        RuiShouAreaConfig areaConfig = config.getRuiShouAreaConfig(areaId);
        if (areaConfig == null) {
            return GameErrorCode.E_RUI_SHOU_AREA_NOT_FOUND;
        }
        if (userData == null) {
            return GameErrorCode.E_RUI_SHOU_USER_NOT_FOUND;
        }
        RuiShouAreaData areaData = getAreaData(areaId);
        if (areaData == null) {
            return GameErrorCode.E_RUI_SHOU_AREA_NOT_FOUND;
        }
        // 判断下奖励选了没有
        int chooseRewardCnt = 0;
        for (RuiShouMonsterData monsterData : areaData.getMonsterDataMap().values()) {
            if (monsterData.getChooseRewardId() != 0) {
                chooseRewardCnt++;
            }
        }
        if (chooseRewardCnt == 0) {
            return GameErrorCode.E_RUI_SHOU_NO_CHOOSE_REWARD;
        }
        // 检测下怪死透了没有
        int aliveCnt = 0;
        for (RuiShouFightMonsterData fightMonsterData : areaData.getFightMonsterDataMap().values()) {
            if (fightMonsterData.getHp() > 0) {
                aliveCnt++;
            }
        }
        if (aliveCnt == 0) {
            return GameErrorCode.E_RUI_SHOU_MONSTER_ALL_KILL;
        }
        // 判断参数合法吗
        // 单次消耗
        Property needCost = PropertyHelper.parseStringToProperty(areaConfig.getNum());
        if (totalTimes == 1) {
            // do something...
        } else if (totalTimes == 10) {
            // 判断下是否开启
            if (userData.getAllKillMonsterCnt() < config.getTenExtractOpen()) {
                return GameErrorCode.E_ERROR_PARAMETER;
            }
            // 总消耗
            needCost.goodCountMultiNum(config.getTenExtractConsume());
        } else {
            // 也判断下是否开启十连抽
            if (userData.getAllKillMonsterCnt() < config.getTenExtractOpen()) {
                return GameErrorCode.E_ERROR_PARAMETER;
            }
            // 总消耗
            needCost.goodCountMultiNum(totalTimes);
        }
        if (!player.getModule(CurrencyModule.class).removeCurrency(needCost, eLogMoneyType.RuiShou, eLogMoneyType.RuiShouShootCost)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        // 锁定奖励状态
        checkLockReward(areaData);
        // 检查区域怪物
        checkAreaMonsterData(areaData);
        // 开抽
        // 表现列表
        List<Integer> actionIdList = new ArrayList<>();
        // 死亡的怪物列表
        List<RuiShouFightMonsterDeadData> deadDataList = new ArrayList<>();
        // 实际抽取次数
        boolean iskillBoss = false;
        // 获得的奖励
        Property getReward = new Property();
        // 记录一下变动前积分
        long logOldScore = userData.getScore();
        for (int times = 0; times < totalTimes; times++) {
            if (areaData.getActionIdPool().isEmpty()) {
                // 抽一个表现池
                NormalWeightItem randomResult = WeightHelper.getRandomResult(config.getActionTenWeightList());
                if (randomResult == null) {
                    continue;
                }
                // 表现组合id
                int actionTenId = randomResult.getValue().intValue();
                RuiShouActionTenConfig actionTenConfig = config.getRuiShouActionTenConfig(actionTenId);
                if (actionTenConfig != null) {
                    for (Integer actionId : actionTenConfig.getActionIdList()) {
                        areaData.getActionIdPool().addLast(actionId);
                    }
                }
            }
            // 做个容错,这里还是空，可能就是配置问题了，玩家可能会丢掉一次，记录下日志
            if (areaData.getActionIdPool().isEmpty()) {
                log.error("【祥瑞赐福】actionIdPool is empty,userId:{}", player.getUserId());
                continue;
            }
            // 本次表现id
            int actionId = areaData.getActionIdPool().removeFirst();
            // 加入列表
            actionIdList.add(actionId);
            // 拿一下表现配置
            RuiShouActionConfig actionConfig = config.getRuiShouActionConfig(actionId);
            if (actionConfig == null) {
                log.error("【祥瑞赐福】actionId not found ,actionId:{},userId:{}", actionId, player.getUserId());
                continue;
            }
            // 判断一下怪物撞击
            for (Integer pos : actionConfig.getMovePath()) {
                if (pos == 0) {
                    // 无撞击
                    continue;
                }
                if (!areaData.getFightMonsterDataMap().containsKey(pos)) {
                    continue;
                }
                RuiShouFightMonsterData fightMonsterData = areaData.getFightMonsterDataMap().get(pos);
                if (fightMonsterData.getId() == 0 || fightMonsterData.getHp() <= 0) {
                    // 已死亡或者空的不处理
                    continue;
                }
                // 最终血量
                fightMonsterData.setHp(fightMonsterData.getHp() - 1);
                if (fightMonsterData.getHp() <= 0) {
                    // 击杀
                    RuiShouFightMonsterDeadData deadData = new RuiShouFightMonsterDeadData();
                    deadData.setId(fightMonsterData.getId());
                    deadData.setPos(fightMonsterData.getPos());
                    deadData.setReward(fightMonsterData.getReward());
                    deadDataList.add(deadData);
                    log.info("【祥瑞赐福】击杀怪物:{},位置:{},获得奖励:{}", fightMonsterData.getId(), fightMonsterData.getPos(), fightMonsterData.getReward());

                    // 生成新的怪物
                    RuiShouFightMonsterData newFightMonsterData = randomFightMonster(areaData, pos);
                    if (newFightMonsterData != null) {
                        areaData.getFightMonsterDataMap().put(pos, newFightMonsterData);
                    }

                    // 击杀的是否为祥瑞
                    RuiShouMonsterConfig deadMonsterConfig = config.getRuiShouMonsterConfig(fightMonsterData.getId());
                    if (deadMonsterConfig.getLevel() == 3) {
                        // 大奖标识
                        iskillBoss = true;
                    }
                }
            }
            // 获得的积分
            Property returnReward = config.getReturnReward(areaId, actionConfig.getReturnPos());
            if (returnReward != null) {
                getReward.addProperty(returnReward);
            }
        }
        if (iskillBoss) {
            // 擊殺祥瑞后可重置
            areaData.setReset(true);
        }
        // 加道具
        for (RuiShouFightMonsterDeadData deadData : deadDataList) {
            getReward.addProperty(PropertyHelper.parseStringToProperty(deadData.getReward()));
        }
        // 获得道具
        player.getModule(CurrencyModule.class).addCurrency(getReward, eLogMoneyType.RuiShou, eLogMoneyType.RuiShouShootGet);
        // 记录一下数据
        for (RuiShouFightMonsterDeadData deadData : deadDataList) {
            userData.addKillMonsterCnt(deadData.getId());
        }
        // 检测下区域解锁
        checkAreaDataLock();

        // 处理下成就
        for (Map.Entry<Integer, BigInteger> entry : needCost.getGoods().entrySet()) {
            Integer goodsId = entry.getKey();
            if (goodsId == config.getRuiShouCostItemId()) {
                // 累计消耗数量
                player.notifyListener(eGamePlayerEventType.RuiShouCostNum.getValue(), entry.getValue().intValue());
            }
        }
        areaData.setUpdateOption();
        userData.setUpdateOption();

        RuiShouProto.RuiShouShootRespMsg.Builder respMsg = RuiShouProto.RuiShouShootRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.addAllActionId(actionIdList);
        for (RuiShouFightMonsterDeadData deadData : deadDataList) {
            respMsg.addDead(RuiShouPb.parseRuiShouShootMonsterDeadDataMsg(deadData));
        }
        respMsg.setAreaData(RuiShouPb.parseRuiShouAreaDataMsg(areaData));
        respMsg.setReward(PropertyHelper.parsePropertyToString(getReward));
        player.sendPacket(ClientProtocol.U_RUI_SHOU_SHOOT, respMsg);

        // 本次结果记录
        List<Map<String, Object>> logMonsterResultList = new ArrayList<>();
        for (RuiShouFightMonsterData monsterData : areaData.getFightMonsterDataMap().values()) {
            if (monsterData.getId() == 0 || monsterData.getHp() == 0) {
                continue;
            }
            Map<String, Object> logMonsterResultMap = new HashMap<>();
            logMonsterResultMap.put("monsterId", monsterData.getId());
            logMonsterResultMap.put("pos", monsterData.getPos());
            logMonsterResultMap.put("hp", monsterData.getHp());
            logMonsterResultList.add(logMonsterResultMap);
        }

        List<Map<String, Object>> logMonsterDeadList = new ArrayList<>();
        for (RuiShouFightMonsterDeadData deadData : deadDataList) {
            if (deadData == null) {
                continue;
            }
            Map<String, Object> logMonsterDeadMap = new HashMap<>();
            logMonsterDeadMap.put("monsterId", deadData.getId());
            logMonsterDeadMap.put("pos", deadData.getPos());
            logMonsterDeadMap.put("reward", deadData.getReward());
            logMonsterDeadList.add(logMonsterDeadMap);
        }

        // 记录一下日志
        AutoLogMgr.add(new LogRuiShouShoot(
                player.getUserId(),
                config.getActivityId(),
                areaId,
                totalTimes,
                PropertyHelper.parsePropertyToString(needCost),
                logMonsterResultList,
                logMonsterDeadList,
                userData.getScore() - logOldScore,
                userData.getScore(),
                new Date()
        ));
        return 0;
    }

    /**
     * 检查区域怪物
     * 目前固定3个，自动补齐
     *
     * @param areaData 区域数据
     */
    public void checkAreaMonsterData(RuiShouAreaData areaData) {
        if (areaData == null) {
            return;
        }
        for (Map.Entry<Integer, RuiShouFightMonsterData> entry : areaData.getFightMonsterDataMap().entrySet()) {
            Integer pos = entry.getKey();
            RuiShouFightMonsterData monsterData = entry.getValue();
            if (monsterData.getId() == 0 || monsterData.getHp() <= 0) {
                // 刷新一只新的来替换
                RuiShouFightMonsterData fightMonsterData = randomFightMonster(areaData, pos);
                if (fightMonsterData != null) {
                    entry.setValue(fightMonsterData);
                }
            }
        }
    }

    /**
     * 获取怪物奖励
     *
     * @param areaId    区域id
     * @param monsterId 怪物id
     */
    public Property getMonsterReward(int areaId, int monsterId) {
        Property property = new Property();
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return property;
        }
        RuiShouMonsterConfig resultMonsterConfig = config.getRuiShouMonsterConfig(monsterId);
        if (!"0".equals(resultMonsterConfig.getRandomAward())) {
            // 随机奖励
            property.addProperty(PropertyHelper.parseNewStringToProperty(resultMonsterConfig.getRandomAward()));
        }
        if (!"0".equals(resultMonsterConfig.getAward())) {
            // 自选奖励
            Integer rewardId = areaDataMap.get(areaId).getChooseRewardId(monsterId);
            if (config.getAwardRewardMap().containsKey(monsterId) && config.getAwardRewardMap().get(monsterId).containsKey(rewardId)) {
                RuiShouMonsterAwardHelper awardHelper = config.getAwardRewardMap().get(monsterId).get(rewardId);
                if (awardHelper != null) {
                    property.addProperty(awardHelper.getReward());
                }
            }
        }
        return property;
    }

    /**
     * 随机一个怪物上战场
     *
     * @param areaData 战场数据
     */
    public RuiShouFightMonsterData randomFightMonster(RuiShouAreaData areaData, int pos) {
        if (areaData == null) {
            return null;
        }
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return null;
        }
        RuiShouAreaConfig areaConfig = config.getRuiShouAreaConfig(areaData.getAreaId());
        if (areaConfig == null) {
            return null;
        }
        // 刷新次数未达到上限且满足保底次数，本次必刷新瑞兽
        List<Integer> leastIdList = new ArrayList<>();
        for (RuiShouMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
            if (monsterConfig.getArea() != areaData.getAreaId()) {
                continue;
            }
            if (areaData.getMonsterFightCnt(monsterConfig.getId()) >= monsterConfig.getNum()) {
                // 达出战次数上限
                continue;
            }
            if (monsterConfig.getLeastNum2() != 0 && areaData.getIncrementCnt(monsterConfig.getId()) >= monsterConfig.getLeastNum2()) {
                // 达到保底
                leastIdList.add(monsterConfig.getId());
            }
        }
        // 先算出当前多少次刷新怪物
        int totalFightCnt = 0;
        for (RuiShouMonsterData monsterData : areaData.getMonsterDataMap().values()) {
            totalFightCnt += monsterData.getFightCnt();
        }

        // 取出最大的保底
        int resultMonsterId = 0;
        int maxLevel = 0;
        for (Integer leastId : leastIdList) {
            RuiShouMonsterConfig monsterConfig = config.getRuiShouMonsterConfig(leastId);
            if (monsterConfig.getLevel() > maxLevel) {
                maxLevel = monsterConfig.getLevel();
                resultMonsterId = leastId;
            }
        }
        // 这里还是0说明上面没触发保底，走正常刷新
        if (resultMonsterId == 0) {
            // 随机刷新
            int totalWeight = 0;
            for (RuiShouMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
                if (monsterConfig.getArea() != areaData.getAreaId()) {
                    continue;
                }
                // 剩下多少只可以刷新
                int leftNum = monsterConfig.getNum() - areaData.getMonsterFightCnt(monsterConfig.getId());
                if (leftNum <= 0) {
                    continue;
                }
                // 未达到多少抽不刷新
                if (monsterConfig.getLeastNum1() != 0 && totalFightCnt + 1 <= monsterConfig.getLeastNum1()) {
                    continue;
                }
                // 加入池子里
                totalWeight += leftNum * monsterConfig.getWeight();
            }
            int randomValue = new RandomHelper().next(0, totalWeight);
            int tempValue = 0;
            for (RuiShouMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
                if (monsterConfig.getArea() != areaData.getAreaId()) {
                    continue;
                }
                // 剩下多少只可以刷新
                int leftNum = monsterConfig.getNum() - areaData.getMonsterFightCnt(monsterConfig.getId());
                if (leftNum <= 0) {
                    continue;
                }
                // 未达到多少抽不刷新
                if (monsterConfig.getLeastNum1() != 0 && totalFightCnt + 1 <= monsterConfig.getLeastNum1()) {
                    continue;
                }
                tempValue += leftNum * monsterConfig.getWeight();
                if(tempValue > randomValue){
                    resultMonsterId = monsterConfig.getId();
                    break;
                }
            }
        }
        if (resultMonsterId == 0) {
            // 没怪了
            return null;
        }
        RuiShouFightMonsterData fightMonsterData = new RuiShouFightMonsterData();
        fightMonsterData.setId(resultMonsterId);
        fightMonsterData.setPos(pos);
        fightMonsterData.setHp(config.getMonsterHp());
        // 获取奖励
        Property monsterReward = getMonsterReward(areaData.getAreaId(), resultMonsterId);
        if (monsterReward != null && !monsterReward.isNothing()) {
            fightMonsterData.setReward(PropertyHelper.parsePropertyToString(monsterReward));
        } else {
            fightMonsterData.setReward("");
        }

        // 记录下刷新次数
        areaData.addMonsterFightCnt(resultMonsterId);

        // 记录增加保底次数
        for (RuiShouMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
            if (monsterConfig.getArea() != areaData.getAreaId()) {
                continue;
            }
            if (monsterConfig.getId() == resultMonsterId) {
                // 重置下次数
                areaData.resetMonsterIncrementCnt(monsterConfig.getId());
            } else {
                // 增加一下计数
                areaData.monsterIncrementCnt(monsterConfig.getId());
            }
        }
        return fightMonsterData;
    }


    /**
     * 添加积分
     */
    public void addScore(long score) {
        if (userData == null) {
            return;
        }
        RuiShouConfig config = RuiShouMgr.getConfig();
        if (config == null) {
            return;
        }
        if (!ActivityHelper.activityInTime(config.getActivityInfo())) {
            // 仅在活动进行中有效
            return;
        }
        userData.setScore(userData.getScore() + score);
        // 更新下榜单
        player.notifyListener(eGamePlayerEventType.RuiShouScoreRank.getValue(), userData.getScore());
    }
}
